package com.yimils.core.sys.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yimils.core.sys.entity.ResourceEntity;
import com.yimils.core.sys.mapper.ResourceMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service("resourceService")
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, ResourceEntity> implements ResourceService {
    @Resource(name = "roleResourceService")
    private RoleResourceService roleResourceService;


    @Override
    public ResourceEntity getParentById(Long id) {
        QueryWrapper<ResourceEntity> qw = new QueryWrapper<>();
        ResourceEntity entity = getById(id);
        qw.lambda().eq(ResourceEntity::getId, entity.getParentId());
        return getOne(qw);
    }

    @Override
    public List<ResourceEntity> getDirs() {
        QueryWrapper<ResourceEntity> qw = new QueryWrapper<>();
        qw.lambda().isNull(ResourceEntity::getParentId);
        return list(qw);
    }

    @Override
    public ResourceEntity getMidParent(ResourceEntity item) {
        QueryWrapper<ResourceEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(ResourceEntity::getParentId, item.getParentId())
                .eq(ResourceEntity::getName, item.getName())
                .eq(ResourceEntity::getOpt, "view");
        return getOne(qw);
    }

    @Override
    public boolean create(ResourceEntity reqParams) {
        if (reqParams.getType().equals(TYPE_SUB)) {
            if (save(reqParams)) {
                List<ResourceEntity> perms = createPerms(reqParams);
                return saveBatch(perms);
            }
        }
        return save(reqParams);
    }

    @Override
    public boolean update(List<ResourceEntity> reqParams) {
        for (ResourceEntity reqParam : reqParams) {
            reqParam.setTitle(reqParam.getTitle().split("-")[0]);
        }
        return saveOrUpdateBatch(reqParams);
    }

    @Transactional
    @Override
    public boolean delete(Long id) {
        QueryWrapper<ResourceEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(ResourceEntity::getId, id);
        ResourceEntity parent = getOne(qw);

        qw.lambda().eq(ResourceEntity::getParentId, parent.getId());
        List<ResourceEntity> children = list(qw);
        if (children != null) {
            List<Long> idList = new ArrayList<>();
            for (ResourceEntity child : children) {
                idList.add(child.getId());
            }
            if (children.size() > 0) {
                removeByIds(idList);
            }
        }
        return removeById(parent.getId());
    }

    @Override
    public List<ResourceEntity> getDirAll() {
        QueryWrapper<ResourceEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(ResourceEntity::getType, TYPE_DIR).orderByAsc(ResourceEntity::getSort);
        return list(qw);
    }

    @Override
    public List<ResourceEntity> getDirByRoleId(Long id) {
        return getBaseMapper().getDirByRoleId(id);
    }

    @Override
    public List<ResourceEntity> getMenuAll(Long dirId) {
        QueryWrapper<ResourceEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(ResourceEntity::getType, TYPE_SUB).eq(ResourceEntity::getParentId, dirId).orderByAsc(ResourceEntity::getSort);
        return list(qw);
    }

    @Override
    public List<ResourceEntity> getMenuByRoleId(Long dirId, Long roleId) {
        return getBaseMapper().getMenuByRoleId(dirId, roleId);
    }

    @Override
    public List<ResourceEntity> getPermAll(Long menuId) {
        QueryWrapper<ResourceEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(ResourceEntity::getType, TYPE_PERM).eq(ResourceEntity::getParentId, menuId);
        return list(qw);
    }

    @Override
    public List<ResourceEntity> getPermByRoleId(Long menuId, Long roleId) {
        return getBaseMapper().getPermByRoleId(menuId, roleId);
    }

    private List<ResourceEntity> createPerms(ResourceEntity reqParams) {
        List<ResourceEntity> perms = new ArrayList<>();
        perms.add(makePerm(reqParams, "view"));
        perms.add(makePerm(reqParams, "add"));
        perms.add(makePerm(reqParams, "update"));
        perms.add(makePerm(reqParams, "remove"));
        return perms;
    }

    private ResourceEntity makePerm(ResourceEntity parent, String opt) {
        ResourceEntity perm = new ResourceEntity();
        perm.setParentId(parent.getId());
        perm.setType(TYPE_PERM);
        perm.setTitle(parent.getTitle());
        perm.setOpt(opt);
        perm.setSort(1);
        perm.setSys(parent.getSys());
        return perm;
    }
}
